package __stack

import (
	"fmt"
	"strings"
)

/**
栈的链表实现
对于链栈来说，基本不存在栈满的情况，除非内存已经没有可以使用的空间
但是我们这里还是设定一个最大值
*/

// StackNode 结点
type StackNode struct {
	data interface{}
	next *StackNode
}

// LinkStack 栈
type LinkStack struct {
	top   *StackNode // 指向栈顶的指针
	count int        // 长度
}

func InitLinkStack() *LinkStack {
	return &LinkStack{}
}

func (l *LinkStack) ClearStack() {
	l.count = 0
	l.top = nil
}

func (l *LinkStack) IsEmpty() bool {
	return l.count == 0
}

func (l *LinkStack) GetTop() interface{} {
	if l.count == 0 || l.top == nil {
		return -1
	}
	return l.top.data
}

func (l *LinkStack) Push(e interface{}) int {
	if l.count == maxSize {
		return -1
	}
	l.count++
	node := &StackNode{data: e, next: l.top}
	l.top = node
	return 0
}

func (l *LinkStack) Pop() interface{} {
	if l.count == 0 || l.top == nil {
		return -1
	}
	r := l.top.data
	l.top = l.top.next
	l.count--
	return r
}

func (l *LinkStack) StackLength() int {
	return l.count
}

func (l *LinkStack) String() string {
	sb := strings.Builder{}
	t := l.top
	for i := 0; i < l.count; i++ {
		sb.WriteString(t.data.(string))
		if i != l.count-1 {
			sb.WriteString("->")
		}
		t = t.next
	}
	return fmt.Sprintf("data=%s, length=%d", sb.String(), l.count)
}
